﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ArtificialIntelligence.CombatComponent;
using Microsoft.Xna.Framework;
using XNA_2DFramwork;

namespace ArtificialIntelligence.MovementComponent.AStar
{
    public static class Path
    {
        public static int JumpRange = 10;
        public static int RunRange = 20;
        public static void FindPathByAStarSearch(List<Node<Vector2>> domain, Node<Vector2> startNode, Node<Vector2> goalNode, Agent agent)
        {
            PathNode pathNode;
            PathNode nextPathNode;
            List<Node<Vector2>> solution = ArtificialIntelligence.MovementComponent.AStar.Solver<Vector2>.Solve(
                startNode,
                goalNode,
                domain.ToArray(),
                (n => Math.Abs((int)n.Value.X - (int)startNode.Value.X) + Math.Abs((int)n.Value.Y - (int)startNode.Value.Y)),
                (n => Math.Abs((int)n.Value.X - (int)goalNode.Value.X) + Math.Abs((int)n.Value.Y - (int)goalNode.Value.Y)),
                ((n, m) => n.Value == m.Value)
                );


            for (int i = 0; i < solution.Count(); i++)
            {
                pathNode = new PathNode();
                //pathNode.Point.X = solution[i].Value.X;
                //pathNode.Point.Y = solution[i].Value.Y;
                pathNode = GetPathNode(solution[i]);

                nextPathNode = new PathNode();

                nextPathNode = GetPathNode(solution[i]);
                //previousPathNode.Point.X = solution[i - 1].PreviousNode.Value.X;
                //previousPathNode.Point.Y = solution[i - 1].PreviousNode.Value.Y;

                pathNode.Command = SetMovementCommand(pathNode, nextPathNode);
                agent.LPath.Add(pathNode);
                //InferenceMachine._domain.Add(pathNode);
            }
        }

        public static MovementCommad SetMovementCommand(PathNode node1, PathNode node2)
        {
            if ((node2.Point.Y) - (node1.Point.Y) > JumpRange)
            {
                return MovementCommad.Jump;
            }
            else
            {
                if ((node2.Point.X) - (node1.Point.X) > RunRange)
                {
                    return MovementCommad.Run;
                }
                else
                {
                    return MovementCommad.Walk;
                }
            }
        }

        public static PathNode GetPathNode(Node<Vector2>node)
        {
            PathNode pathNode =  new PathNode();
            pathNode.Point.X = node.Value.X;
            pathNode.Point.Y = node.Value.Y;
            return pathNode;
        }

        public static Node<Vector2> GetNodeOfVector2(Vector2 vector2)
        {
            Node<Vector2> node = new Node<Vector2>();
            //Point p = new Point((int)vector2.X, (int) vector2.Y);
            node.Value= vector2;
            return node;
        }

        public static List<Node<Vector2>> GetListNodeOfVector2(List<PathNode>list)
        {
            List<Node<Vector2>> LVector2 = new List<Node<Vector2>>();
         
            foreach (PathNode pathNode in list)
            {
                LVector2.Add( GetNodeOfVector2(pathNode.Point));
            }
            return LVector2;
        }
    }
}
